package net.stogi.dsper.back.dao.impl;

import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import net.stogi.dsper.api.model.DataField;
import net.stogi.dsper.api.model.DataObject;
import net.stogi.dsper.api.model.DataSource;
import net.stogi.dsper.back.dao.FeedDao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.stereotype.Repository;

import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;

@Repository
public class FeedRomeDaoImpl implements FeedDao {

	private static final String DEFAULT_AUTHOR_FIELD_NAME = "author";

	private static final String DEFAULT_DESCRIPTION_FIELD_NAME = "description";

	private static final String DEFAULT_LINK_FIELD_NAME = "link";

	private static final String DEFAULT_PUBLISHED_DATE_FIELD_NAME = "publishedDate";

	private static final String DEFAULT_TITLE_FIELD_NAME = "title";

	private static final Logger log = LoggerFactory.getLogger(FeedRomeDaoImpl.class);

	@Override
	public List<DataObject> loadDataEntries(DataSource dataSource) {
		log.trace("loadDataEntries(): invoke: [dataSource = '{}']", dataSource);
		assert dataSource != null : "Parameter 'dataSource' can not be null";

		SyndFeedInput feedInput = new SyndFeedInput();

		List<DataObject> dataObjectList = new ArrayList<DataObject>();

		try {
			SyndFeed feed = feedInput.build(new XmlReader(new URL(dataSource.getUrl())));

			Iterator<?> it = feed.getEntries().iterator();
			while (it.hasNext()) {
				SyndEntry entry = (SyndEntry) it.next();

				DataObject dataObject = new DataObject();

				DataField dataField = new DataField();
				dataField.setName(DEFAULT_TITLE_FIELD_NAME);
				dataField.setValue(entry.getTitle());
				dataObject.getDataFields().put(DEFAULT_TITLE_FIELD_NAME, dataField);

				dataField = new DataField();
				dataField.setName(DEFAULT_PUBLISHED_DATE_FIELD_NAME);
				dataField.setValue(entry.getPublishedDate() != null ? entry.getPublishedDate().toString() : null);
				dataObject.getDataFields().put(DEFAULT_PUBLISHED_DATE_FIELD_NAME, dataField);

				dataField = new DataField();
				dataField.setName(DEFAULT_AUTHOR_FIELD_NAME);
				dataField.setValue(entry.getAuthor());
				dataObject.getDataFields().put(DEFAULT_AUTHOR_FIELD_NAME, dataField);

				dataField = new DataField();
				dataField.setName(DEFAULT_LINK_FIELD_NAME);
				dataField.setValue(entry.getLink());
				dataObject.getDataFields().put(DEFAULT_LINK_FIELD_NAME, dataField);

				dataField = new DataField();
				dataField.setName(DEFAULT_DESCRIPTION_FIELD_NAME);
				dataField.setValue(entry.getDescription() != null ? entry.getDescription().getValue() : null);
				dataObject.getDataFields().put(DEFAULT_DESCRIPTION_FIELD_NAME, dataField);

				dataObjectList.add(dataObject);
			}
		}
		catch (Exception e) {
			log.warn("Some problems with RSS / Atom source", e);
			throw new DataAccessResourceFailureException("Some problems with RSS / Atom source", e);
		}

		return dataObjectList;
	}
}
